package com.ktg.mes.wm.service.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.common.core.domain.model.SqlResult;
import com.ktg.common.utils.StringUtils;
import com.ktg.mes.md.vo.QueryVo;
import com.ktg.mes.unit.other.SQLListenerInterface;
import com.ktg.mes.unit.other.SQLListenerType;
import com.ktg.mes.unit.sql.service.SQLToolService;
import com.ktg.mes.unit.sync.SyncModel;
import com.ktg.mes.unit.sync.service.IFromService;
import com.ktg.mes.wm.domain.WmItemRecptLine;
import com.ktg.mes.wm.domain.WmMaterialStock;
import com.ktg.mes.wm.mapper.WmMaterialStockMapper;
import com.ktg.mes.wm.service.IWmMaterialStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


/**
 * 库存记录Service业务层处理
 *
 * @author yinjinlu
 * @date 2022-05-24
 */
@Service
public class WmMaterialStockServiceImpl  extends ServiceImpl<WmMaterialStockMapper, WmMaterialStock> implements IWmMaterialStockService
{

    @Autowired
    private IFromService fromService;

    @Autowired
    private SQLToolService toIService;


    /**
     * 查询库存记录
     *
     * @param materialStockId 库存记录主键
     * @return 库存记录
     */
    @Override
    public WmMaterialStock selectWmMaterialStockByMaterialStockId(Long materialStockId)
    {
        return getBaseMapper().selectWmMaterialStockByMaterialStockId(materialStockId);
    }

    /**
     * 查询库存记录列表
     *
     * @param wmMaterialStock 库存记录
     * @return 库存记录
     */
    @Override
    public List<WmMaterialStock> selectWmMaterialStockList(WmMaterialStock wmMaterialStock)
    {
        return getBaseMapper().selectWmMaterialStockList(wmMaterialStock);
    }

    /**
     * 查询库存记录列表
     *
     * @param stock 库存记录
     * @return 库存记录集合
     */
    public WmMaterialStock loadMaterialStock(WmMaterialStock stock){
        QueryWrapper<WmMaterialStock> lqw = new QueryWrapper<>();
        if (stock.getItemId() != null){
            lqw.eq("item_id",stock.getItemId());
        }
        if (StringUtils.isEmpty(stock.getUnitOfMeasure())){
            lqw.eq("unit_of_measure",stock.getUnitOfMeasure());
        }
        if (StringUtils.isEmpty(stock.getBatchCode())){
            lqw.eq("batch_code",stock.getBatchCode());
        }
        if (stock.getWarehouseId() != null){
            lqw.eq("warehouse_id",stock.getWarehouseId());
        }
        if (stock.getLocationId() != null){
            lqw.eq("location_id",stock.getLocationId());
        }
        if (stock.getAreaId() != null){
            lqw.eq("area_id",stock.getAreaId());
        }
        if (stock.getVendorId() != null){
            lqw.eq("vendor_id",stock.getVendorId());
        }
        lqw.orderByDesc("create_time");
        lqw.last(" limit 0,1");
        return getOne(lqw);
    }


    private static Lock lock = new ReentrantLock();



    /**
     * 修改批次号的库存信息
     * @param item
     */
    public void updateStockQuantity(WmMaterialStock item){
        getBaseMapper().updateStockQuantity(item);
    }

    @Override
    public IPage<Map> selectStockList(QueryVo vo) {
        Page<Map> page = new Page<Map>(vo.getPageNo(), vo.getPageSize());
        WmMaterialStock stock = new WmMaterialStock();
        if(vo.getItemCode() != null){
            stock.setItemCode(vo.getItemCode());
        }
        if(vo.getWarehouseId() != null){
            stock.setWarehouseId(vo.getWarehouseId());
        }
        if(StringUtils.isNotEmpty(vo.getItemName())){
            stock.setItemName(vo.getItemName());
        }
        IPage<Map> ipage = getBaseMapper().selectStockList(page,stock);
        return ipage;
    }

    @Override
    public void cleanData() {
        getBaseMapper().deleteMaterialStock();
    }

    ;


    //监听入库记录变化
    @SQLListenerInterface(tableName = "wm_item_recpt_line",listerType = {SQLListenerType.BeforeAll})
    public SqlResult wmItemRecptLineListener(SQLListenerType type, WmItemRecptLine oldObj, WmItemRecptLine newObj) {
        //统计出库
        try {
            if (type == SQLListenerType.AddBefore
                    || type == SQLListenerType.ChangeBefore
                    || type == SQLListenerType.DeleteBefore){

                WmMaterialStock materialStock = new WmMaterialStock();

                if (oldObj != null && newObj != null
                        && oldObj.getIsInStock().equals("1")
                        && newObj.getIsInStock().equals("1")
                        && oldObj.getMaterialStockKey().equals(newObj.getMaterialStockKey())
                        ){
                    float newCount = newObj.getQuantity().floatValue();
                    float oldCount = oldObj.getQuantity().floatValue();
                    materialStock.setItemCode(oldObj.getItemCode());
                    materialStock.setWarehouseCode(oldObj.getWarehouseCode());
                    materialStock.setBatchCode(oldObj.getBatchCode());
                    materialStock = getOne(new QueryWrapper<>(materialStock));
                    materialStock.setQuantityOnhand(BigDecimal.valueOf(materialStock.getQuantityOnhand().floatValue() - oldCount + newCount));
                    updateById(materialStock);
                }else {
                    if (oldObj != null && oldObj.getIsInStock().equals("1") ){
                        float oldCount = oldObj.getQuantity().floatValue();
                        materialStock.setItemCode(oldObj.getItemCode());
                        materialStock.setWarehouseCode(oldObj.getWarehouseCode());
                        materialStock.setBatchCode(oldObj.getBatchCode());
                        materialStock = getOne(new QueryWrapper<>(materialStock));

                        if (materialStock != null){
                            materialStock.setQuantityOnhand(BigDecimal.valueOf(materialStock.getQuantityOnhand().floatValue() - oldCount));
                            updateById(materialStock);
                        }

                    }
                    if (newObj != null && newObj.getIsInStock().equals("1")){
                        float newCount = newObj.getQuantity().floatValue();
                        materialStock.setItemCode(newObj.getItemCode());
                        materialStock.setWarehouseCode(newObj.getWarehouseCode());
                        materialStock.setBatchCode(newObj.getBatchCode());

                        materialStock = getOne(new QueryWrapper<>(materialStock));

                        if (materialStock == null){
                            materialStock = new WmMaterialStock();
                            materialStock.setItemTypeId(Long.valueOf(newObj.getInType()));
                            materialStock.setItemId(newObj.getItemId());
                            materialStock.setItemCode(newObj.getItemCode());
                            materialStock.setItemName(newObj.getItemName());
                            materialStock.setSpecification(newObj.getSpecification());
                            materialStock.setUnitOfMeasure(newObj.getUnitOfMeasure());
                            materialStock.setViscosity(newObj.getViscosity());
                            materialStock.setPackingType(newObj.getPackingType());
                            materialStock.setTag(newObj.getTag());

                            materialStock.setWarehouseId(newObj.getWarehouseId());
                            materialStock.setWarehouseCode(newObj.getWarehouseCode());
                            materialStock.setWarehouseName(newObj.getWarehouseName());
                            materialStock.setBatchCode(newObj.getBatchCode());

                            materialStock.setQuantityOnhand(BigDecimal.valueOf(newCount));
                            save(materialStock);
                        }else {
                            materialStock.setQuantityOnhand(BigDecimal.valueOf(materialStock.getQuantityOnhand().floatValue() + newCount));
                            updateById(materialStock);
                        }
                    }
                }

            }
        }catch (Exception e){
            e.printStackTrace();
            return SqlResult.error(this.getClass().toString(),e);
        }
        return SqlResult.ok(null,newObj);
    }

    /**
     * 同步库存
     */
    public synchronized void sysnStock(){
        getBaseMapper().deleteMaterialStock();
        SyncModel syncModel = new SyncModel();
        syncModel.setService(fromService,toIService);
        String tableName = "(SELECT\n" +
                "\tMAX(AutoID) as AutoID,cInvCode,cBatch,cWhCode,cWhName,cBarCode,cInvName,cInvStd,cInvDefine1,cInvDefine2,cInvDefine3,SUM (quantity) AS iQuantity\n" +
                "FROM\n" +
                "\t(\n" +
                "\tSELECT\n" +
                "\t\tAutoID,\n" +
                "\t\tCurrentStock.cBatch,\n" +
                "\t\tCurrentStock.cWhCode,\n" +
                "\t\tcWhName,\n" +
                "\t\tWarehouse.cBarCode,\n" +
                "\t\tCurrentStock.cInvCode,\n" +
                "\t\tcInvName,\n" +
                "\t\tcInvStd,\n" +
                "\t\tcInvDefine1,\n" +
                "\t\tcInvDefine2,\n" +
                "\t\tcInvDefine3,\n" +
                "\t\t(iQuantity + fOutQuantity + fInQuantity) AS quantity \n" +
                "\tFROM\n" +
                "\t\tCurrentStock\n" +
                "\t\tLEFT JOIN Inventory ON CurrentStock.cInvCode = Inventory.cInvCode\n" +
                "\t\tLEFT JOIN Warehouse ON CurrentStock.cWhCode = Warehouse.cWhCode\n" +
                "\t) P where quantity > 0 GROUP BY cInvCode,cBatch,cWhCode,cWhName,cBarCode,cInvName,cInvStd,cInvDefine1,cInvDefine2,cInvDefine3)P";

        syncModel.setTable(tableName,"wm_material_stock");
        syncModel.setSyncData("AutoID",null,"material_stock_id",null);

        syncModel.addColumn("AutoID","material_stock_id", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cBatch","batch_code", SyncModel.SyncModelType.TypeString);

        syncModel.addColumn("cWhCode","warehouse_id", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cBarCode","warehouse_code", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cWhName","warehouse_name", SyncModel.SyncModelType.TypeString);

        syncModel.addColumn("cInvCode","item_code", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvName","item_name", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvStd","specification", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvDefine1","viscosity", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvDefine2","tag", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvDefine3","packing_type", SyncModel.SyncModelType.TypeString);

        syncModel.addColumn("iQuantity","quantity_onhand", SyncModel.SyncModelType.TypeString);

        syncModel.synsStart("库存信息");

        getBaseMapper().updateProductItemId();
        getBaseMapper().updateWareHouseId();
    }







}
